package com.koron.tool.service.impl;

import com.koron.bean.base.Response;
import com.koron.tool.bean.ToolGroupBean;
import com.koron.tool.bean.ToolWarningInfoBean;
import com.koron.tool.enums.InventoryCycleEnum;
import com.koron.tool.enums.WarningReasonEnum;
import com.koron.tool.mapper.ToolWarningInfoMapper;
import com.koron.tool.service.ToolWarningInfoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.TaskAnnotation;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;


/**
 * @Author: laiguangming
 * @Date: 2022/10/20 9:46
 */
@Slf4j
@Service
public class ToolWarningInfoServiceImpl implements ToolWarningInfoService {

    @Override
    @TaskAnnotation("getWarningInfoList")
    public Response getWarningInfoList(SessionFactory sessionFactory) {
        try {
            ToolWarningInfoMapper mapper = sessionFactory.getMapper(ToolWarningInfoMapper.class);
            // 查询预警信息（即将到达校验器/报废期、盘点账物不符）
            List<ToolWarningInfoBean> list = mapper.getWarningInfoList();
            Map<Integer, String> map = WarningReasonEnum.getWarningReasonMap();
            list.forEach(bean -> {
                bean.setReasonDescription(map.get(bean.getReason()));
            });

            // 查询预警信息（即将到达盘点期）
            List<ToolGroupBean> toolGroupBeanList = mapper.getInventoryCycleWarningInfo();
            List<ToolWarningInfoBean> inventoryCycleWarningInfoList = new ArrayList<>();
            LocalDateTime now = LocalDateTime.now();
            toolGroupBeanList.forEach(toolGroupBean -> {
                // 查询下一次盘点时间（盘点当天截止时间24:00）
                LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(toolGroupBean.getInventoryStartDate(), 0, ZoneOffset.ofHours(8)).plusDays(1);
                Integer inventoryCycle = toolGroupBean.getInventoryCycle();
                while (localDateTime.isBefore(now)) {
                    if (Objects.equals(inventoryCycle, InventoryCycleEnum.MONTH.getValue())) {
                        localDateTime = localDateTime.plusMonths(1);
                    } else if (Objects.equals(inventoryCycle, InventoryCycleEnum.QUARTER.getValue())) {
                        localDateTime = localDateTime.plusMonths(3);
                    } else if (Objects.equals(inventoryCycle, InventoryCycleEnum.YEAR.getValue())) {
                        localDateTime = localDateTime.plusYears(1);
                    } else {
                        break;
                    }
                }
                // 生成7天内+1天盘点当天需要进行库房盘点的预警信息
                // 判断条件由不等式l-7<n<l得来，操作数-8和16是因为数据库存的时间是8:00
                if (now.isAfter(localDateTime.plusDays(-8)) && now.isBefore(localDateTime)) {
                    ToolWarningInfoBean toolWarningInfoBean = new ToolWarningInfoBean();
                    toolWarningInfoBean.setDate(localDateTime.toInstant(ZoneOffset.ofHours(8)).getEpochSecond());
                    toolWarningInfoBean.setReason(WarningReasonEnum.REACT_THE_INVENTORY_PERIOD.getReason());
                    toolWarningInfoBean.setReasonDescription(WarningReasonEnum.REACT_THE_INVENTORY_PERIOD.getReasonDescription());
                    toolWarningInfoBean.setBelongsStationId(toolGroupBean.getParent());
                    toolWarningInfoBean.setBelongsStationName(toolGroupBean.getParentName());
                    toolWarningInfoBean.setWarehouseId(toolGroupBean.getWarehouseId());
                    toolWarningInfoBean.setWarehouseName(toolGroupBean.getWarehouseName());
                    inventoryCycleWarningInfoList.add(toolWarningInfoBean);
                }
            });
            if (CollectionUtils.isNotEmpty(inventoryCycleWarningInfoList)) {
                list.addAll(inventoryCycleWarningInfoList);
            }
            return Response.ok(list);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Response.fail();
        }
    }

}
